package com.gu.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.boot.entity.SecurityUser;
import com.boot.entity.User;
import com.boot.exception.DiyException;
import com.gu.entity.AclRolePermission;
import com.gu.entity.AclUser;
import com.gu.entity.AclUserRole;
import com.gu.service.AclPermissionService;
import com.gu.service.AclRolePermissionService;
import com.gu.service.AclUserRoleService;
import com.gu.service.AclUserService;
import org.springframework.beans.BeanUtils;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * Description: spring-security
 * 加载用户特定数据的核心接口。自定义数据校验查询；
 * 它在整个框架中用作用户 DAO，是DaoAuthenticationProvider使用的策略。
 * 该接口只需要一种只读方法，这简化了对新数据访问策略的支持。
 *
 * @Autor: Rolin
 * datetime: 07-13-21:15
 */

@Service
public class UserDetailsServicesImpl implements UserDetailsService {

    @Resource
    private AclUserService aclUserService;

    @Resource
    private AclPermissionService aclPermissionService;
    @Resource
    private AclUserRoleService aclUserRoleService;
    @Resource
    private AclRolePermissionService aclRolePermissionService;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        //1.从数据库中查询出userName的对象信息；
        QueryWrapper<AclUser> wrapper = new QueryWrapper<>();
        wrapper.eq("username", username);
        AclUser aclUser = aclUserService.getOne(wrapper);
        if (Objects.isNull(aclUser)) {
            throw new DiyException("444", "该用户不存在，请重新登录");
        }
        //2.生成userDetails对象返回,SecurityUser为其实现类；
        SecurityUser securityUser = new SecurityUser();
        User user = new User();
        BeanUtils.copyProperties(aclUser, user);

        //3.获取该用户所对应的权限信息；
        String id = aclUser.getId();
        // 3.1获取用户对于的角色
        QueryWrapper<AclUserRole> aclUserRoleQueryWrapper = new QueryWrapper<>();
        aclUserRoleQueryWrapper.eq("user_id", id);
        AclUserRole role = aclUserRoleService.getOne(aclUserRoleQueryWrapper);
        String roleId = role.getId();

        //3.2获取roleId所对应的菜单ID
        QueryWrapper<AclRolePermission> aclRolePermissionQueryWrapper = new QueryWrapper<>();
        aclRolePermissionQueryWrapper.eq("role_id", roleId);
        List<AclRolePermission> rolePermissions = aclRolePermissionService.list(aclRolePermissionQueryWrapper);

        //3.3根据Id来查询 菜单 并且封装成 List<String>
        List<String> permissionValueList =
                rolePermissions
                .stream()
                .map(rolePermission -> aclPermissionService.getById(rolePermission.getId()).getPermissionValue())
                .collect(Collectors.toList());

        //4.封装权限
        securityUser.setPermissionValueList(permissionValueList);
        return securityUser;
    }
}
